1 package edu.jiangxin.apktoolbox.convert.protobuf.supervised; 2 3 import edu.jiangxin.apktoolbox.convert.protobuf.unsupervised.ByteUtil; 4 import edu.jiangxin.apktoolbox.swing.extend.EasyPanel; 5 import edu.jiangxin.apktoolbox.swing.extend.filepanel.FilePanel; 6 import edu.jiangxin.apktoolbox.utils.Constants; 7 import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; 8 import org.fife.ui.rsyntaxtextarea.SyntaxConstants; 9 import org.fife.ui.rtextarea.RTextScrollPane; 10 11 import javax.swing.*; 12 import java.awt.*; 13 import java.io.File; 14 import java.io.PrintWriter; 15 import java.io.Serial; 16 import java.io.StringWriter; 17 import java.nio.file.Path; 18 19 public class SupervisedProtobufConvertPanel extends EasyPanel { 20 @Serial 21 private static final long serialVersionUID = 1L; 22 23 private FilePanel descriptorCachePanel; 24 25 private JPanel contentPanel; 26 27 private JPanel operationPanel; 28 29 private JTextArea inputTextArea; 30 private RSyntaxTextArea outputTextArea; 31 32 @Override 33 public void initUI() { 34 BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS); 35 setLayout(boxLayout); 36 37 createDescriptorCachePanel(); 38 add(descriptorCachePanel); 39 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER)); 40 41 createContentPanel(); 42 add(contentPanel); 43 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER)); 44 45 createOperationPanel(); 46 add(operationPanel); 47 } 48 49 private void createDescriptorCachePanel() { 50 descriptorCachePanel = new FilePanel("Descriptor Cache Directory"); 51 descriptorCachePanel.initialize(); 52 descriptorCachePanel.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 53 } 54 55 private void createContentPanel() { 56 contentPanel = new JPanel(); 57 58 BoxLayout boxLayout = new BoxLayout(contentPanel, BoxLayout.X_AXIS); 59 contentPanel.setLayout(boxLayout); 60 61 inputTextArea = new JTextArea(); 62 inputTextArea.setLineWrap(true); 63 inputTextArea.setWrapStyleWord(true); 64 inputTextArea.setText("0a2f0a084a6f686e20446f6510011a106a6f686e406578616d706c652e636f6d220f0a0b3131312d3232322d33333310010a1e0a084a616e6520446f6510021a106a616e65406578616d706c652e636f6d"); 65 66 JScrollPane inputScrollPanel = new JScrollPane(inputTextArea); 67 inputScrollPanel.setPreferredSize(new Dimension(200, 500)); 68 69 outputTextArea = new RSyntaxTextArea(); 70 outputTextArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON); 71 outputTextArea.setCodeFoldingEnabled(true); 72 outputTextArea.setEditable(false); 73 74 RTextScrollPane outputScrollPane = new RTextScrollPane(outputTextArea); 75 outputScrollPane.setPreferredSize(new Dimension(200, 500)); 76 77 contentPanel.add(inputScrollPanel); 78 contentPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER)); 79 contentPanel.add(outputScrollPane); 80 } 81 82 private void createOperationPanel() { 83 operationPanel = new JPanel(); 84 85 BoxLayout boxLayout = new BoxLayout(operationPanel, BoxLayout.X_AXIS); 86 operationPanel.setLayout(boxLayout); 87 88 JButton convertButton = new JButton("Convert"); 89 90 convertButton.addActionListener(e -> convertProtoToJson()); 91 92 operationPanel.add(convertButton); 93 } 94 95 private void convertProtoToJson() { 96 try { 97 String hexString = inputTextArea.getText(); 98 byte[] byteArray = ByteUtil.hex2bytes(hexString); 99 File descriptorCacheDirectory = descriptorCachePanel.getFile(); 100 Path path = descriptorCacheDirectory.toPath(); 101 final DescriptorCache cache = DescriptorCache.fromDirectory(path); 102 if (cache.isEmpty()) { 103 displayErrorMessage( 104 "The descriptor cache is empty, could not load any descriptor, check the cache directory:\n" 105 + path.toAbsolutePath(), "Empty descriptor cache" 106 ); 107 return; 108 } 109 110 final ProtoToJson protoToJson = ProtoToJson.fromCache(cache); 111 final String jsonString; 112 try { 113 jsonString = protoToJson.toJson(byteArray); 114 } catch (final RuntimeException e) { 115 displayErrorMessage( 116 "Unable to find a descriptor matching the given JSON message, check the cache directory:\n" 117 + path.toAbsolutePath(), "No matching descriptor found" 118 ); 119 return; 120 } 121 122 outputTextArea.setText(jsonString); 123 } catch (final Throwable t) { 124 final StringWriter sw = new StringWriter(); 125 final PrintWriter pw = new PrintWriter(sw); 126 t.printStackTrace(pw); 127 displayErrorMessage(sw.toString(), "Error"); 128 } 129 } 130 131 private static void displayErrorMessage(final String message, final String title) { 132 JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE); 133 } 134 }